//
//  CZStatusDAL.swift
//  GZWeibo666
//
//  Created by iOS on 15/12/11.
//  Copyright © 2015年 itcast. All rights reserved.
//

import UIKit

/// 加载微博数据,有2中加载方式
class CZStatusDAL: NSObject {
    
    // 单例
    static let sharedInstance = CZStatusDAL()
    
    // overTime
    let overTime: NSTimeInterval = 60 // 7 * 24 * 60 * 60 // 7天
    
    private override init() {
        super.init()
    }
    
    /// 清理过期的微博数据
    func clearCachedStatus() {
        // 计算过期时间
        let date = NSDate(timeIntervalSinceNow: -overTime)
        print("过期时间: date: \(date)")
        
        // 时间格式化
        let df = NSDateFormatter()
        df.locale = NSLocale(localeIdentifier: "en")
        df.dateFormat = "yyyy-MM-dd HH:mm:ss"
        let overTimeString = df.stringFromDate(date)
        print("overTimeString: \(overTimeString)")
        
        // 确定sql语句
        let sql = "DELETE FROM T_Status WHERE createAt < '\(overTimeString)';"
        
        CZSQLiteManager.sharedManager.dbQueue.inTransaction { (db, rollback) -> Void in
            if db.executeUpdate(sql) {
                print("删除缓存数据成功")
            } else {
                print("删除缓存数据失败")
                rollback.memory = true
            }
        }
    }

    /*
        加载微博数据
            1. 查找本地数据库
            2. 如果有数据直接返回
            3. 如果没有数据,发送网络请求加载网络上的数据
            4. 保存网络数据到数据库 (先保证数据库有数据)
            5. 将网络数据返回给调用者
    */
    func loadStatus(since_id: Int, max_id: Int, finished: (status: [[String: AnyObject]]?, error: NSError?) -> ()) {
        // 1. 查找本地数据库
        loadCacheStatus(since_id, max_id: max_id) { (statues) -> () in
            if statues != nil && statues?.count > 0 {
                print("本地加载微博数据")
                // TODO: 返回数据
                // 2. 如果有数据直接返回
                finished(status: statues, error: nil)
                return
            }
            
            // 能到这里来说明本地数据库没有数据
            // 3. 如果没有数据,发送网络请求加载网络上的数据
            CZNetworkTool.sharedInstance.loadStatus(since_id, max_id: max_id, finished: { (result, error) -> () in
                // 判断是否加载成功
                if error != nil || result == nil {
                    print("网络加载数据失败")
                    // 告诉调用者加载数据失败
                    finished(status: nil, error: error)
                    return
                }
                
                // 加载数据成功
                if let array = result?["statuses"] as? [[String: AnyObject]] {
                    // 解析到微博数据
                    // 4. 保存网络数据到数据库
                    self.saveStatus(array)
                    
                    // 5. 将网络数据返回给调用者
                    finished(status: array, error: nil)
                } else {
                    // 告诉调用者没有新数据
                    finished(status: nil, error: nil)
                }
            })
        }
    }
    
    /**
    到数据库加载微博
    */
    private func loadCacheStatus(since_id: Int, max_id: Int, finished: (statues: [[String: AnyObject]]?) -> ()) {
        // 获取用户的id
        assert(CZUserAccount.loadUserAccount()?.uid != nil, "账户没有uid")
        
        let uid = Int(CZUserAccount.loadUserAccount()!.uid!)!
        
        // sql
        var sql = "SELECT * FROM T_Status \n" +
        "WHERE userId = \(uid) \n"
            
        // since_id 下拉刷新, 不能少这个, 如果少了，就会从数据库加载20数据statusId没有限制,只有数据加载不道数据,才去网络上加载
        if since_id > 0 {
            sql += "AND statusId > \(since_id) \n"
        } else if max_id > 0 {  // 加载更多数据
            sql += "AND statusId < \(max_id) \n"
        }
        
        sql += "ORDER BY statusId DESC LIMIT 20;"
        
        print("查询 sql : \(sql)")
        
        // 执行查询sql获取数据库中的数据
        CZSQLiteManager.sharedManager.dbQueue.inDatabase { (db) -> Void in
            guard let result = db.executeQuery(sql) else {
                print("没有查询到数据")
                return finished(statues: nil)
            }
            
            // 查询到数据
            // 将查询到的数据转成数组字典返回
            var statues = [[String: AnyObject]]()
            
            while result.next() {
                // 获取数据
                let statusString = result.stringForColumn("status")
                
                // String -> NSData -> JSON
                let data = statusString.dataUsingEncoding(NSUTF8StringEncoding)!
                
                // 微博字典
                let status = try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0)) as! [String: AnyObject]
                
                statues.append(status)
            }
            
            finished(statues: statues)
        }
    }
    
    /**
    保存微博数据到数据
    
    - parameter statues: 微博数据的数组,一条微博数据对应一个字典
    */
    private func saveStatus(statues: [[String: AnyObject]]) {
        // 获取用户的id
        assert(CZUserAccount.loadUserAccount()?.uid != nil, "账户没有uid")
        
        let uid = Int(CZUserAccount.loadUserAccount()!.uid!)!
        
        // OR REPLACE 替换数据
        // 替换主键相同的数据,必须要有主键
        // 主键不能是自动增长的
        let sql = "INSERT OR REPLACE INTO T_Status (statusId, status, userId) VALUES (?, ?, ?)"
        // 像数据库添加数据
        CZSQLiteManager.sharedManager.dbQueue.inTransaction { (db, rollback) -> Void in
            
            // 遍历出每一条微博数据
            for status in statues {
                // 获取微博的id
                let statusId = status["id"] as! Int
                
                // 数据库中不能直接存放字典,可以存放字符串
                // 字典(json) -> NSData -> String
                let data = try! NSJSONSerialization.dataWithJSONObject(status, options: NSJSONWritingOptions(rawValue: 0))
                
                // 微博内容字符串
                let statusString = String(data: data, encoding: NSUTF8StringEncoding)!
                
                // 保存到数据库
                if db.executeUpdate(sql, statusId, statusString, uid) {
                    print("添加微博数据到数据库: \(statusId)")
                }
            }
        }
        
    }
}
